﻿using NeXus;
using NeXus.BIMBase;
using NeXus.BIMBase.Core;
using NeXus.BIMBase.Data;
using NeXus.BIMBase.SolidCore;
using NeXus.p3d;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using static NeXus.p3d.GeCurveArray;

namespace BimBaseInterfaceTesting.Interface
{
    class CreateCulvertAisle
    {
        //##########################涵洞通道-YBL################################

        public CulvertAisleElement culvertAisleElement;
        /// <summary>
        /// 创建通道
        /// </summary>
        /// <param name="culvertAisleParameter">参数</param>
        public CreateCulvertAisle(CulvertAisleParameter culvertAisleParameter)
        {
            culvertAisleParameter.culvertBottomSlope = culvertAisleParameter.culvertBottomSlope / 100;
            
            #region 创建搁置板、盖板、挡块
            double LateralOffset = Math.Abs((culvertAisleParameter.spanLength / 2) * Math.Tan((90 - culvertAisleParameter.angle_L) * Math.PI / 180));
            double LateralOffset_R = Math.Abs((culvertAisleParameter.spanLength / 2) * Math.Tan((90 - culvertAisleParameter.angle_R) * Math.PI / 180));
            culvertAisleParameter.length += LateralOffset + LateralOffset_R;
            BPGraphics shelveSE_L = null;
            BPGraphics cuboidSE_L = null;
            BPGraphics stopDogSE_L = null;
            BPGraphics shelveSE_R = null;
            BPGraphics cuboidSE_R = null;
            BPGraphics stopDogSE_R = null;
            if (culvertAisleParameter.isGutterway)
            {
                if (culvertAisleParameter.gutterwayLocation == "左侧" || culvertAisleParameter.gutterwayLocation == "两侧")
                {
                    //搁置板
                    shelveSE_L = CreateCuboid( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, 0), culvertAisleParameter.shelveWidth_L, culvertAisleParameter.stopDogHigh_L - culvertAisleParameter.CoverPlateThickness_L, culvertAisleParameter.length, culvertAisleParameter.culvertBottomSlope,culvertAisleParameter.chamferLength);

                    //盖板
                    cuboidSE_L = CreateCuboid( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, culvertAisleParameter.stopDogHigh_L - culvertAisleParameter.CoverPlateThickness_L), culvertAisleParameter.shelveWidth_L + culvertAisleParameter.gutterwayWidth_L + culvertAisleParameter.bracketWidth_L, culvertAisleParameter.CoverPlateThickness_L, culvertAisleParameter.length, culvertAisleParameter.culvertBottomSlope);

                    //挡块
                    stopDogSE_L = CreateStopDog(true,  new GePoint3d(-(culvertAisleParameter.spanLength / 2) + culvertAisleParameter.shelveWidth_L + culvertAisleParameter.gutterwayWidth_L + culvertAisleParameter.stopDogThickness_L, 0, 0), culvertAisleParameter.stopDogSlope_L, culvertAisleParameter.bracketWidth_L, culvertAisleParameter.stopDogThickness_L, culvertAisleParameter.stopDogHigh_L, culvertAisleParameter.CoverPlateThickness_L, culvertAisleParameter.length, culvertAisleParameter.culvertBottomSlope);
                }

                if (culvertAisleParameter.gutterwayLocation == "右侧" || culvertAisleParameter.gutterwayLocation == "两侧")
                {
                    //搁置板
                    shelveSE_R = CreateCuboid( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, 0), culvertAisleParameter.shelveWidth_R, culvertAisleParameter.stopDogHigh_R - culvertAisleParameter.CoverPlateThickness_R, culvertAisleParameter.length, culvertAisleParameter.culvertBottomSlope, culvertAisleParameter.chamferLength);

                    //盖板
                    cuboidSE_R = CreateCuboid( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, culvertAisleParameter.stopDogHigh_R - culvertAisleParameter.CoverPlateThickness_R), culvertAisleParameter.shelveWidth_R + culvertAisleParameter.gutterwayWidth_R + culvertAisleParameter.bracketWidth_R, culvertAisleParameter.CoverPlateThickness_R, culvertAisleParameter.length, culvertAisleParameter.culvertBottomSlope);

                    //挡块
                    stopDogSE_R = CreateStopDog(false,  new GePoint3d(culvertAisleParameter.spanLength / 2 - culvertAisleParameter.shelveWidth_R - culvertAisleParameter.gutterwayWidth_R - culvertAisleParameter.stopDogThickness_R, 0, 0), culvertAisleParameter.stopDogSlope_R, culvertAisleParameter.bracketWidth_R, culvertAisleParameter.stopDogThickness_R, culvertAisleParameter.stopDogHigh_R, culvertAisleParameter.CoverPlateThickness_R, culvertAisleParameter.length, culvertAisleParameter.culvertBottomSlope);
                }
            }
            #endregion

            #region 铺装
            List<BPGraphics> matFoemationSEList = new List<BPGraphics>();
            //铺装实时厚度 
            double matFormationSumThickness = 0;
            for (int i = culvertAisleParameter.matFormation_dgv.RowCount - 1; i >= 0; i--)
            {
                //铺装厚度
                double matFormationThickness = Convert.ToDouble(culvertAisleParameter.matFormation_dgv[1, i].Value) / 100;
                //铺装材料
                //string matFormationMaterials =culvertAisleParameter.matFormation_dgv[2, i].Value.ToString();
                //路拱横坡
                double crossSlope = Convert.ToDouble(culvertAisleParameter.matFormation_dgv[3, i].Value);
                List<GePoint3d> matFormationPoint = new List<GePoint3d>();

                if ((culvertAisleParameter.gutterwayLocation == "左侧" || culvertAisleParameter.gutterwayLocation == "两侧") && matFormationSumThickness < culvertAisleParameter.stopDogHigh_L)
                {
                    matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2) + culvertAisleParameter.shelveWidth_L + culvertAisleParameter.gutterwayWidth_L + culvertAisleParameter.stopDogThickness_L, 0, matFormationSumThickness));

                    if (matFormationSumThickness + matFormationThickness > culvertAisleParameter.stopDogHigh_L)
                    {
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2) + culvertAisleParameter.shelveWidth_L + culvertAisleParameter.gutterwayWidth_L + culvertAisleParameter.stopDogThickness_L, 0, culvertAisleParameter.stopDogHigh_L));
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, culvertAisleParameter.stopDogHigh_L));
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, matFormationSumThickness + matFormationThickness));
                    }
                    else
                    {
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2) + culvertAisleParameter.shelveWidth_L + culvertAisleParameter.gutterwayWidth_L + culvertAisleParameter.stopDogThickness_L, 0, matFormationSumThickness + matFormationThickness));
                    }
                }
                else
                {
                    if (i == 0 && culvertAisleParameter.chamferLength != 0)
                    {
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2) + culvertAisleParameter.chamferLength, 0, matFormationSumThickness));
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, matFormationSumThickness + culvertAisleParameter.chamferLength));
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, matFormationSumThickness + matFormationThickness));
                    }
                    else
                    {
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, matFormationSumThickness));
                        matFormationPoint.Add( new GePoint3d(-(culvertAisleParameter.spanLength / 2), 0, matFormationSumThickness + matFormationThickness));
                    }

                }
                List<GePoint3d> point_R = new List<GePoint3d>();
                if ((culvertAisleParameter.gutterwayLocation == "右侧" || culvertAisleParameter.gutterwayLocation == "两侧") && matFormationSumThickness < culvertAisleParameter.stopDogHigh_R)
                {
                    point_R.Add( new GePoint3d((culvertAisleParameter.spanLength / 2) - culvertAisleParameter.shelveWidth_R - culvertAisleParameter.gutterwayWidth_R - culvertAisleParameter.stopDogThickness_R, 0, matFormationSumThickness));
                    if (matFormationSumThickness + matFormationThickness > culvertAisleParameter.stopDogHigh_L)
                    {
                        point_R.Add( new GePoint3d((culvertAisleParameter.spanLength / 2) - culvertAisleParameter.shelveWidth_L - culvertAisleParameter.gutterwayWidth_L - culvertAisleParameter.stopDogThickness_L, 0, culvertAisleParameter.stopDogHigh_L));
                        point_R.Add( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, culvertAisleParameter.stopDogHigh_L));
                        point_R.Add( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, matFormationSumThickness + matFormationThickness));
                    }
                    else
                    {
                        point_R.Add( new GePoint3d((culvertAisleParameter.spanLength / 2) - culvertAisleParameter.shelveWidth_R - culvertAisleParameter.gutterwayWidth_R - culvertAisleParameter.stopDogThickness_R, 0, matFormationSumThickness + matFormationThickness));
                    }
                }
                else
                {
                    if (i == 0 && culvertAisleParameter.chamferLength != 0)
                    {
                        point_R.Add( new GePoint3d(culvertAisleParameter.spanLength / 2 - culvertAisleParameter.chamferLength, 0, matFormationSumThickness));
                        point_R.Add( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, matFormationSumThickness + culvertAisleParameter.chamferLength));
                        point_R.Add( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, matFormationSumThickness + matFormationThickness));
                    }
                    else
                    {
                        point_R.Add( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, matFormationSumThickness));
                        point_R.Add( new GePoint3d(culvertAisleParameter.spanLength / 2, 0, matFormationSumThickness + matFormationThickness));
                    }

                }
                if (i == 0 && crossSlope != 0)
                {
                    GePoint3d crossSlope_L = matFormationPoint[matFormationPoint.Count - 1];
                    GePoint3d crossSlope_R = point_R[point_R.Count - 1];
                    double b = crossSlope_L.z - crossSlope * crossSlope_L.x;
                    double y = crossSlope * ((crossSlope_L.x + crossSlope_R.x) / 2) + b;
                    GePoint3d crossSlopePOint =  new GePoint3d((crossSlope_L.x + crossSlope_R.x) / 2, 0, y);
                    matFormationPoint.Add(crossSlopePOint);
                }
                point_R.Reverse();
                matFormationPoint.AddRange(point_R);
                BPGraphics matFoemationSE = CreatePointSmartSolid(matFormationPoint, culvertAisleParameter.length, culvertAisleParameter.culvertBottomSlope);
                matFormationSumThickness += matFormationThickness;
                matFoemationSEList.Add(matFoemationSE);
            }
            #endregion 

            #region 创建剪切体
            culvertAisleParameter.length -= (LateralOffset + LateralOffset_R);

            List<List<GePoint3d>> lstSlab_Dpoint = new List<List<GePoint3d>>();
            if (culvertAisleParameter.angle_L < 90)
            {
                List<GePoint3d> clipDpointHead = new List<GePoint3d>()
                {
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),LateralOffset,-100),
                  new GePoint3d(culvertAisleParameter.spanLength/2,-LateralOffset,-100),
                  new GePoint3d(culvertAisleParameter.spanLength/2,-LateralOffset,100),
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),LateralOffset,100),
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),LateralOffset,-100),
                };
                lstSlab_Dpoint.Add(clipDpointHead);
            }
            else
            {
                List<GePoint3d> clipDpointHead = new List<GePoint3d>()
                {
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),-LateralOffset,-100),
                  new GePoint3d(culvertAisleParameter.spanLength/2,LateralOffset,-100),
                  new GePoint3d(culvertAisleParameter.spanLength/2,LateralOffset,100),
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),-LateralOffset,100),
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),-LateralOffset,-100),
                };
                lstSlab_Dpoint.Add(clipDpointHead);
            }

            if (culvertAisleParameter.angle_R < 90)
            {
                List<GePoint3d> clipDpointTrail = new List<GePoint3d>()
                {
                     new GePoint3d(-(culvertAisleParameter.spanLength/2),culvertAisleParameter.length+LateralOffset_R,-100),
                     new GePoint3d(culvertAisleParameter.spanLength/2,culvertAisleParameter.length-LateralOffset_R,-100),
                     new GePoint3d(culvertAisleParameter.spanLength/2,culvertAisleParameter.length-LateralOffset_R,100),
                     new GePoint3d(-(culvertAisleParameter.spanLength/2),culvertAisleParameter.length+LateralOffset_R,100),
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),culvertAisleParameter.length+LateralOffset_R,-100),
                };
                lstSlab_Dpoint.Add(clipDpointTrail);
            }
            else
            {
                List<GePoint3d> clipDpointTrail = new List<GePoint3d>()
                {
                     new GePoint3d(-(culvertAisleParameter.spanLength/2),culvertAisleParameter.length-LateralOffset_R,-100),
                  new GePoint3d(culvertAisleParameter.spanLength/2,culvertAisleParameter.length+LateralOffset_R,-100),
                     new GePoint3d(culvertAisleParameter.spanLength/2,culvertAisleParameter.length+LateralOffset_R,100),
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),culvertAisleParameter.length-LateralOffset_R,100),
                  new GePoint3d(-(culvertAisleParameter.spanLength/2),culvertAisleParameter.length-LateralOffset_R,-100),
                };
                lstSlab_Dpoint.Add(clipDpointTrail);
            }

            #endregion

            #region 剪切通道体的头尾
            culvertAisleElement = new CulvertAisleElement();
            double z = culvertAisleParameter.culvertBottomSlope * -LateralOffset;

            GeTransform transMovePoint = GeTransform.create(0, -LateralOffset, z);
            if (shelveSE_L != null)
            {
                IGeSolidBase solidLoseY = CreatePointSmartSolid(lstSlab_Dpoint[0], culvertAisleParameter.length*10,false);
                IGeSolidBase solidJustY = CreatePointSmartSolid(lstSlab_Dpoint[1], culvertAisleParameter.length * 10, true);
                BPGraphics graphicSubstract = new BPGraphics(new BPModelPtr());
                graphicSubstract.addGeSolidBase(solidLoseY);
                graphicSubstract.addGeSolidBase(solidJustY);
                BPGraphicsUtils.transformPhysicalGraphics(shelveSE_L, transMovePoint);
                //布尔求差值
                BPGraphics bPGraphics= BoolDifferenceSet(shelveSE_L,graphicSubstract);
                culvertAisleElement.shelveElement_L = bPGraphics;
            }
            if (cuboidSE_L != null)
            {
                IGeSolidBase solidLoseY  = CreatePointSmartSolid(lstSlab_Dpoint[0], culvertAisleParameter.length * 10, false);
                IGeSolidBase solidJustY = CreatePointSmartSolid(lstSlab_Dpoint[1], culvertAisleParameter.length * 10, true);
                BPGraphics graphicSubstract = new BPGraphics(new BPModelPtr());
                graphicSubstract.addGeSolidBase(solidLoseY);
                graphicSubstract.addGeSolidBase(solidJustY);
                BPGraphicsUtils.transformPhysicalGraphics(cuboidSE_L, transMovePoint);
                //布尔求差值
                BPGraphics bPGraphics = BoolDifferenceSet(cuboidSE_L,graphicSubstract);
                culvertAisleElement.cuboidElement_L = bPGraphics;
            }
            if (stopDogSE_L != null)
            {
                IGeSolidBase solidLoseY = CreatePointSmartSolid(lstSlab_Dpoint[0], culvertAisleParameter.length * 10, false);
                IGeSolidBase solidJustY = CreatePointSmartSolid(lstSlab_Dpoint[1], culvertAisleParameter.length * 10, true);
                BPGraphics graphicSubstract = new BPGraphics(new BPModelPtr());
                graphicSubstract.addGeSolidBase(solidLoseY);
                graphicSubstract.addGeSolidBase(solidJustY);
                BPGraphicsUtils.transformPhysicalGraphics(stopDogSE_L, transMovePoint);
                //布尔求差值
                BPGraphics bPGraphics = BoolDifferenceSet(stopDogSE_L,graphicSubstract);
                culvertAisleElement.stopDogElement_L = bPGraphics;
            }
            if (shelveSE_R != null)
            {
                IGeSolidBase solidLoseY = CreatePointSmartSolid(lstSlab_Dpoint[0], culvertAisleParameter.length * 10, false);
                IGeSolidBase solidJustY = CreatePointSmartSolid(lstSlab_Dpoint[1], culvertAisleParameter.length * 10, true);
                BPGraphics graphicSubstract = new BPGraphics(new BPModelPtr());
                graphicSubstract.addGeSolidBase(solidLoseY);
                graphicSubstract.addGeSolidBase(solidJustY);
                BPGraphicsUtils.transformPhysicalGraphics(shelveSE_R, transMovePoint);
                //布尔求差值
                BPGraphics bPGraphics = BoolDifferenceSet(shelveSE_R,graphicSubstract);
                culvertAisleElement.shelveElement_R = bPGraphics;
            }
            if (cuboidSE_R != null)
            {
                IGeSolidBase solidLoseY = CreatePointSmartSolid(lstSlab_Dpoint[0], culvertAisleParameter.length * 10, false);
                IGeSolidBase solidJustY = CreatePointSmartSolid(lstSlab_Dpoint[1], culvertAisleParameter.length * 10, true);
                BPGraphics graphicSubstract = new BPGraphics(new BPModelPtr());
                graphicSubstract.addGeSolidBase(solidLoseY);
                graphicSubstract.addGeSolidBase(solidJustY);
                BPGraphicsUtils.transformPhysicalGraphics(cuboidSE_R, transMovePoint);
                //布尔求差值
                BPGraphics bPGraphics = BoolDifferenceSet(cuboidSE_R,graphicSubstract);
                culvertAisleElement.cuboidElement_R = bPGraphics;
            }
            if (stopDogSE_R != null)
            {
                IGeSolidBase solidLoseY = CreatePointSmartSolid(lstSlab_Dpoint[0], culvertAisleParameter.length * 10, false);
                IGeSolidBase solidJustY = CreatePointSmartSolid(lstSlab_Dpoint[1], culvertAisleParameter.length * 10, true);
                BPGraphics graphicSubstract = new BPGraphics(new BPModelPtr());
                graphicSubstract.addGeSolidBase(solidLoseY);
                graphicSubstract.addGeSolidBase(solidJustY);
                BPGraphicsUtils.transformPhysicalGraphics(stopDogSE_R, transMovePoint);
                //布尔求差值
                BPGraphics bPGraphics = BoolDifferenceSet(stopDogSE_R,graphicSubstract);
                culvertAisleElement.stopDogElement_R = bPGraphics;
            }
            foreach (BPGraphics item in matFoemationSEList)
            {
                if (item == null)
                    continue;
                BPGraphics bPGraphics = item;
                IGeSolidBase solidLoseY = CreatePointSmartSolid(lstSlab_Dpoint[0], culvertAisleParameter.length * 10, false);
                IGeSolidBase solidJustY = CreatePointSmartSolid(lstSlab_Dpoint[1], culvertAisleParameter.length * 10, true);
                BPGraphics graphicSubstract = new BPGraphics(new BPModelPtr());
                graphicSubstract.addGeSolidBase(solidLoseY);
                graphicSubstract.addGeSolidBase(solidJustY);
                BPGraphicsUtils.transformPhysicalGraphics(bPGraphics, transMovePoint);
                //布尔求差值
                BPGraphics bPGraphicsOut = BoolDifferenceSet(bPGraphics,graphicSubstract);
                culvertAisleElement.matFoemationElement.Add(bPGraphicsOut);
            }
            #endregion
        }

        /// <summary>
        /// 创建长方体
        /// </summary>
        /// <param name="location">基准点(针对左边为左下)</param>
        /// <param name="width">搁置板宽度</param>
        /// <param name="high">搁置板高度</param>
        /// <param name="length">体长</param>
        /// <param name="dgnModel">放置视图</param>
        /// <returns></returns>
        private BPGraphics CreateCuboid(GePoint3d location, double width, double high, double length, double culvertSlope, double chamferLength = 0)
        {
            GePoint3d GePoint3d =  new GePoint3d(0, 0, location.z);
            if (chamferLength == 0)
            {
                List<GePoint3d> points = new List<GePoint3d>()
                {
                    location ,
                    GetNformMNAndLL(location,GePoint3d,width),
                   new GePoint3d(GetNformMNAndLL(location,GePoint3d,width).x,GetNformMNAndLL(location,GePoint3d,width).y,GetNformMNAndLL(location,GePoint3d,width).z+high),
                   new GePoint3d(location.x,location.y,location.z+high),
                  location
                };
                return CreatePointSmartSolid(points, length, culvertSlope);
            }
            else
            {
                List<GePoint3d> points = new List<GePoint3d>()
                {
                   new GePoint3d(location.x,location.y,location.z+chamferLength),
                    GetNformMNAndLL(location,GePoint3d,chamferLength),
                    GetNformMNAndLL(location,GePoint3d,width),
                   new GePoint3d(GetNformMNAndLL(location,GePoint3d,width).x,GetNformMNAndLL(location,GePoint3d,width).y,GetNformMNAndLL(location,GePoint3d,width).z+high),
                   new GePoint3d(location.x,location.y,location.z+high),
                   new GePoint3d(location.x,location.y,location.z+chamferLength)
                };
                return CreatePointSmartSolid(points, length, culvertSlope);
            }
        }

        /// <summary>
        /// 创建挡块
        /// </summary>
        /// <param name="isLeft">是否为左边</param>
        /// <param name="location">基准点（针对左边为右下）</param>
        /// <param name="slope">挡块坡度</param>
        /// <param name="bracketWidth">牛腿宽</param>
        /// <param name="stopDogThickness">挡块厚</param>
        /// <param name="stopDogHigh">挡块高</param>
        /// <param name="CoverPlateThickness">盖板厚</param>
        /// <param name="length">体长</param>
        /// <returns></returns>
        private BPGraphics CreateStopDog(bool isLeft, GePoint3d location, double slope, double bracketWidth, double stopDogThickness, double stopDogHigh, double CoverPlateThickness, double length, double culvertSlope)
        {
            List<GePoint3d> stopDogPoint = new List<GePoint3d>();

            double slopeWidth = (stopDogHigh - CoverPlateThickness) * slope;
            if (isLeft)
            {
                List<GePoint3d> points = new List<GePoint3d>()
                {
                    location,
                     new GePoint3d(location.x,location.y,location.z+stopDogHigh),
                     new GePoint3d(location.x-(stopDogThickness-bracketWidth),location.y,location.z+stopDogHigh),
                     new GePoint3d(location.x-(stopDogThickness-bracketWidth),location.y,location.z+stopDogHigh-CoverPlateThickness),
                     new GePoint3d(location.x-stopDogThickness,location.y,location.z+stopDogHigh-CoverPlateThickness),
                     new GePoint3d(location.x-stopDogThickness-slopeWidth,location.y,location.z),
                    location
                };
                stopDogPoint = points;
            }
            else
            {
                List<GePoint3d> points = new List<GePoint3d>()
                {
                    location,
                     new GePoint3d(location.x,location.y,location.z+stopDogHigh),
                     new GePoint3d(location.x+(stopDogThickness-bracketWidth),location.y,location.z+stopDogHigh),
                     new GePoint3d(location.x+(stopDogThickness-bracketWidth),location.y,location.z+stopDogHigh-CoverPlateThickness),
                     new GePoint3d(location.x+stopDogThickness,location.y,location.z+stopDogHigh-CoverPlateThickness),
                     new GePoint3d(location.x+stopDogThickness+slopeWidth,location.y,location.z),
                    location
                };
                stopDogPoint = points;
            }
            return CreatePointSmartSolid(stopDogPoint, length, culvertSlope);
        }

        /// <summary>
        /// 创建实体 点集有分辨率
        /// </summary>
        /// <param name="points"></param>
        /// <param name="Width"></param>
        private BPGraphics CreatePointSmartSolid(List<GePoint3d> points, double Width, double slope)
        {
            double b = points[0].z  - slope * points[0].y ;
            double z = slope * (points[0].y  + Width) + b;
            //面
            GeCurveArrayPtr curveList = GeCurveArray.create(BoundaryType.BOUNDARY_TYPE_Outer);
            for (int i = 0; i < points.Count; i++)
            {
                if(i== points.Count - 1)
                {
                    //线
                    var curve = IGeCurveBase.createSegment(new GeSegment3d(points[i], points[0]));
                    curveList.add(curve);
                }
                else
                {
                    //线
                    var curve = IGeCurveBase.createSegment(new GeSegment3d(points[i], points[i + 1]));
                    curveList.add(curve);
                }         
            }
            //体
            GeVec3d v3d = GeVec3d.createByStartEnd(points[0], new GePoint3d(points[0].x, points[0].y + Width, z));
            GeExtrusionInfo extrusionInfo = new GeExtrusionInfo(curveList, v3d, true);
            var solid = IGeSolidBase.createGeExtrusion(extrusionInfo);
            BPGraphics graphic = new BPGraphics(new BPModelPtr());
            graphic.addSolid(solid);
            //graphic.save();
            return graphic;
        }

        /// <summary>
        /// 创建实体 点集有分辨率
        /// </summary>
        /// <param name="points"></param>
        /// <param name="Width"></param>
        /// <param name="GeVec3dY">  true=>正  false=>负 </param>
        private IGeSolidBase CreatePointSmartSolid(List<GePoint3d> points, double Width,bool GeVec3dY)
        {
            //面
            GeCurveArrayPtr curveList = GeCurveArray.create(BoundaryType.BOUNDARY_TYPE_Outer);
            for (int i = 0; i < points.Count; i++)
            {
                if (i == points.Count - 1)
                {
                    //线
                    var curve = IGeCurveBase.createSegment(new GeSegment3d(points[i], points[0]));
                    curveList.add(curve);
                }
                else
                {
                    //线
                    var curve = IGeCurveBase.createSegment(new GeSegment3d(points[i], points[i + 1]));
                    curveList.add(curve);
                }
            }
            //体
            GeVec3d v3d = GeVec3dY==true? GeVec3d.createByStartEnd(points[0], new GePoint3d(points[0].x, points[0].y + Width, points[0].z)): GeVec3d.createByStartEnd(points[0], new GePoint3d(points[0].x, points[0].y - Width, points[0].z));
            GeExtrusionInfo extrusionInfo = new GeExtrusionInfo(curveList, v3d, true);
            IGeSolidBasePtr solid = IGeSolidBase.createGeExtrusion(extrusionInfo);
            
            return solid.get();
        }

        /// <summary>
        /// 计算延长点
        /// </summary>
        /// <param name="M">原点</param>
        /// <param name="N">指向点</param>
        /// <param name="LL">指定延长的长度</param>
        /// <returns></returns>
        private GePoint3d GetNformMNAndLL(GePoint3d pointA, GePoint3d pointB, double Length)
        {
            GeVec3d ab = GeVec3d.createByStartEnd(pointA, pointB);
            //长度*AB的单位向量 单位向量 = 向量 / 向量的模 
            GeVec3d normalize = GeVec3d.createByStartEndNormalize(pointA, pointB);
            double UnitVector_X = Length * normalize.x;
            double UnitVector_Y = Length * normalize.y;
            double UnitVector_Z = Length * normalize.z;
            //向量AL的L点的坐标
            double NewPoint_X = pointA.x + UnitVector_X;
            double NewPoint_Y = pointA.y + UnitVector_Y;
            double NewPoint_Z = pointA.z + UnitVector_Z;
            //Console.WriteLine("该点的坐标是:<" + NewPoint_X + "," + NewPoint_Y + ">");
            GePoint3d point = new GePoint3d(NewPoint_X, NewPoint_Y, NewPoint_Z);
            return point;
        }

        /// <summary>
        /// 布尔差集（画笔）
        /// </summary>
        /// <param name="graphic1">第一个几何实体画笔</param>
        /// <param name="graphic2">第二个几何实体画笔</param>
        private  BPGraphics BoolDifferenceSet(BPGraphics graphic1, BPGraphics graphic2)
        {
            BPProject project = BPApplication.getInstance().getProjectManager().getMainProject();
            BPModelBase model = project.getActiveModel();

            //布尔计算
            BPGraphicsPtr graphicBool = model.createPhysicalGraphics();

            int tolerance = 0;
            BPSolidBooleanUtil.getAngleTolerance(ref tolerance);
            BPSolidBooleanUtil.setAngleTolerance(36);//布尔前将精度设置为36，防止布尔导致的面片变形
            P3DStatus status = BPSolidBooleanUtil.doBoolean(graphicBool, graphic1.getEntityR(), graphic2.getEntityR(), BPBooleanOp.Substract);
            
            return graphicBool.get();
        }
    }

    public class CulvertAisleElement
    {
        public BPGraphics shelveElement_L;
        public BPGraphics cuboidElement_L;
        public BPGraphics stopDogElement_L;
        public BPGraphics shelveElement_R;
        public BPGraphics cuboidElement_R;
        public BPGraphics stopDogElement_R;
        public List<BPGraphics> matFoemationElement = new List<BPGraphics>();
    }

    public class CulvertAisleParameter
    {
        //跨径
        public double spanLength;
        //左角度
        public double angle_L;
        //右角度
        public double angle_R;
        //涵底坡度
        public double culvertBottomSlope;
        //涵洞长
        public double length;
        //倒角
        public double chamferLength;
        //铺装
        public DataGridView matFormation_dgv;
        //是否设置排水沟
        public bool isGutterway;
        //排水沟位置
        public string gutterwayLocation;
        //两侧尺寸
        public string twoFlanksSize;
        //挡块材料
        //public string stopDogMaterials;
        //盖板材料
        //public string coverPlateMaterials;
        //搁置板材料
        //public string shelveMaterials;

        //左侧挡块高度
        public double stopDogHigh_L;
        //左侧挡块厚度
        public double stopDogThickness_L;
        //左侧牛腿宽
        public double bracketWidth_L;
        //左侧排水沟宽
        public double gutterwayWidth_L;
        //左侧盖板厚度
        public double CoverPlateThickness_L;
        //左侧搁置板宽
        public double shelveWidth_L;
        //左侧挡块坡度
        public double stopDogSlope_L;

        //右侧挡块高度
        public double stopDogHigh_R;
        //右侧挡块厚度
        public double stopDogThickness_R;
        //右侧牛腿宽
        public double bracketWidth_R;
        //右侧排水沟宽
        public double gutterwayWidth_R;
        //右侧盖板厚度
        public double CoverPlateThickness_R;
        //右侧搁置板宽
        public double shelveWidth_R;
        //右侧挡块坡度
        public double stopDogSlope_R;
    }
}
